/***********************************************************************//**
 \file SampleSndFile.h		\author belot nicolas (karrakis)
\brief define Class SampleSndFile
	Work with a sample compatible with SndFile

 ************************************************************************//*
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
****************************************************************************/

#ifndef SAMPLE_SND_FILE_H
#define SAMPLE_SND_FILE_H

#include "Sample.h"
#include "Buffer.h"
#include <sndfile.h>
namespace libtrckr {
class SampleSndFile : public Sample {
/** \class libtrckr::SampleSndFile
 \brief Load and Read Sample in any Format known by libsndfile
*/
#define	STR_WAV		"Microsoft WAV format"
#define	STR_AIFF	"Apple/SGI AIFF format"
#define	STR_AU		"Sun/NeXT AU format"
#define	STR_RAW		"RAW PCM data"
#define	STR_PAF		"Ensoniq PARIS file format"
#define	STR_SVX		"Amiga IFF / SVX8 / SV16 format"
#define	STR_NIST	"Sphere NIST format"
#define	STR_VOC		"VOC files"
#define	STR_IRCAM	"Berkeley/IRCAM/CARL"
#define	STR_W64		"Sonic Foundry's 64 bit RIFF/WAV"
#define	STR_MAT4	"Matlab (tm) V4.2 / GNU Octave 2.0"
#define	STR_MAT5	"Matlab (tm) V5.0 / GNU Octave 2.1"
#define	STR_PVF		"Portable Voice Format"
#define	STR_XI		"Fasttracker 2 Extended Instrument"
#define	STR_HTK		"HMM Tool Kit format"
#define	STR_SDS		"Midi Sample Dump Standard"
#define	STR_AVR		"Audio Visual Research"
#define	STR_WAVEX	"MS WAVE with WAVEFORMATEX"
#define	STR_SD2		"Sound Designer 2"
#define	STR_FLAC	"FLAC lossless file format"
#define	STR_CAF		"Core Audio File format"
#define	STR_WVE		"Psion WVE format"

	/* Subtypes from here on. */

#define	STR_PCM_S8	"Signed 8 bit data"
#define	STR_PCM_16	"Signed 16 bit data"
#define	STR_PCM_24	"Signed 24 bit data"
#define	STR_PCM_32	"Signed 32 bit data"

#define	STR_PCM_U8	"Unsigned 8 bit data"

#define	STR_FLOAT	"32 bit float data"
#define	STR_DOUBLE	"64 bit float data"

#define	STR_ULAW	"U-Law encoded"
#define	STR_ALAW	"A-Law encoded"
#define	STR_IMA_ADPCM	"IMA ADPCM"
#define	STR_MS_ADPCM	"Microsoft ADPCM"

#define	STR_GSM610	"GSM 6.10 encoding"
#define	STR_VOX_ADPCM	"OKI / Dialogix ADPCM"

#define	STR_G721_32	"32kbs G721 ADPCM encoding"
#define	STR_G723_24	"24kbs G723 ADPCM encoding"
#define	STR_G723_40	"40kbs G723 ADPCM encoding"

#define	STR_DWVW_12	"12 bit Delta Width Variable Word encoding"
#define	STR_DWVW_16	"16 bit Delta Width Variable Word encoding"
#define	STR_DWVW_24	"24 bit Delta Width Variable Word encoding"
#define	STR_DWVW_N	"N bit Delta Width Variable Word encoding"

#define	STR_DPCM_8	"8 bit differential PCM"
#define	STR_DPCM_16	"16 bit differential PCM"

	public :
	//constructor
		//SampleSndFile();
		//SampleSndFile(int ); //Fd
		/** Constructor 
		\warning SampleSndFile \b should \b not be created directly, instead use \c SampleFactory::newSample(filename)
		\param filename the file containing the sample
		*/
		SampleSndFile(const char *);//Filename
				/** Constructor 
		\warning SampleSndFile \b should \b not be created directly, instead use SampleFactory::newSample(filename)
		\param filename the file containing the sample
		*/
		SampleSndFile(string); //Filename
		/**Copy constructor
		\param s the sample
		*/
		SampleSndFile(SampleSndFile&);
	//Destrcutor
		~SampleSndFile();

	//reader
		/** Read data from the sample
			read count \c double from the sample and load them in the buffer.
		\param buffer the buffer
		\param count the number of items
		\return the number of really read item
		*/
		loff_t  read(double*, int );//read int double
		/** Read data from the sample
			read count \c float from the sample and load them in the buffer.
		\param buffer the buffer
		\param count the number of items
		\return the number of really read item
		*/
		loff_t  read(float*, int );
		/** Read data from the sample
			read count \c int from the sample and load them in the buffer.
		\param buffer the buffer
		\param count the number of items
		\return the number of really read item
		*/
		loff_t  read(int*, int );
		/** Read data from the sample
			read count \c short from the sample and load them in the buffer.
		\param buffer the buffer
		\param count the number of items
		\return the number of really read item
		*/
		loff_t  read(short *,int );
		/** read count data 
		\param count the number of item
		\return an \c Buffer containing data
		*/
		Buffer read(int);
		/** Load the buffer with data
		\param b the buffer to fill
		*/
		void read(Buffer&);
		/** did we reach the end of the file
		\return a boolean ...
		*/
		bool isEOF() const;
	//Accessor
		/** return a string with the format of the Sample*/
		string getFormat(); //A string Format  dataType XI PCM 16 bit
		/** Set the format
		\param type the type of the Sample WAV etc
		\param sub  the encoding, 32bit etc
		\param endianness the endianness
		*/
		void setFormat(int,int,int);
		/** Position the handle in the adress
		\param  where ^^
		\return true on success false otherwise
		*/
		bool seek(long); 
		/** return the length of the sample
		\return an \c loff_t
		*/
		loff_t getLength( ) const;
		/** is this Sample valid SndFileSample */
		bool isValid() const;
		int channels() const;
	private :
		static double* buff;//an internal buffer for some read/write operation
		static uint bsize; // the size of this buffer
		static int nb; //count of SndFileSample...

		SNDFILE * 	_handler;
		struct SF_INFO*	_sfinfo;
		loff_t 		_lastreadcount;
		loff_t		_position;
		string		_format;
};
}
#endif


